import SimpleITK as sitk
import os
import time
from glob import glob
import numpy as np 

def writeSlices(series_tag_values, new_img, i, out_dir):
    image_slice = new_img[:,:,i]
    writer = sitk.ImageFileWriter()
    writer.KeepOriginalImageUIDOn()

    # Tags shared by the series.
    list(map(lambda tag_value: image_slice.SetMetaData(tag_value[0], tag_value[1]), series_tag_values))

    # Slice specific tags.
    image_slice.SetMetaData("0008|0012", time.strftime("%Y%m%d")) # Instance Creation Date
    image_slice.SetMetaData("0008|0013", time.strftime("%H%M%S")) # Instance Creation Time

    # Setting the type to CT preserves the slice location.
    image_slice.SetMetaData("0008|0060", "CT")  # set the type to CT so the thickness is carried over

    # (0020, 0032) image position patient determines the 3D spacing between slices.
    image_slice.SetMetaData("0020|0032", '\\'.join(map(str,new_img.TransformIndexToPhysicalPoint((0,0,i))))) # Image Position (Patient)
    image_slice.SetMetaData("0020|0013", str(i+1)) # Instance Number
    image_slice.SetMetaData("0020|9057", str(i+1)) # InStackPositionNumber
    image_slice.SetMetaData("0020|0012", "1") # AcquisitionNumber
    image_slice.SetMetaData("0018|0086", "1") # EchoNumbers




    print(i)
    # Write to the output directory and add the extension dcm, to force writing in DICOM format.
    writer.SetFileName(os.path.join(out_dir,'slice' + str(i).zfill(4) + '.dcm'))
    writer.Execute(image_slice)


def nifti2dicom_1file(in_dir, out_dir):
    """
    This function is to convert only one nifti file into dicom series

    `nifti_dir`: the path to the one nifti file
    `out_dir`: the path to output
    """

    os.makedirs(out_dir, exist_ok=True)

    new_img_fp32 = sitk.ReadImage(in_dir)
    image_arr = sitk.GetArrayFromImage(new_img_fp32).astype(np.int16)

    new_img = sitk.GetImageFromArray(image_arr)
    new_img.SetDirection(new_img_fp32.GetDirection())
    new_img.SetSpacing(new_img_fp32.GetSpacing())

    modification_time = time.strftime("%H%M%S")
    modification_date = time.strftime("%Y%m%d")

    direction = new_img.GetDirection()
    series_tag_values = [
                    # ("0002|0002", "1.2.840.10008.5.1.4.1.1.4"),	
                    # ("0008|0005", "ISO_IR 100"), # Series Time
                    ("0008|0031",modification_time), # Series Time
                    ("0008|0021",modification_date), # Series Date
                    ("0008|0008","ORIGINAL\PRIMARY\OTHER"), # Image Type

                    ("0020|0011", "92"), ## series number
                    # ("0020|0010", "123"),
                    # ("0020|0011", "1"),
                    ("0020|000D", "1.3.6.1.4.1.14519.5.2.1.7311.5101.170561193612723093192571245493"), # Study instance uid. requirted
                    # ("0008|0016", "1.2.840.10008.5.1.4.1.1.4"), # SOPClassUID,
                    # ("0008|0018", "1.3.6.1.4.1.14519.5.2.1.7311.5101.140661212185680998225449002612"), ## SOPInstanceUID	 不能使用，用的话就成一个slice了
                   
                    # ("0020|000e", "1.3.6.1.4.1.14519.5.2.1.3671.4754.230497515093449653192531406300"),
                    ("0020|000e", "1.2.826.0.1.3680043.2.1125."+modification_date+".1"+modification_time), # Series Instance UID. requirted
                    ("0018|0088", "3.5"), ## slice spacing
                    # ("0020|1041", "-8.1410404145954"), 
                    ("0018|0050", "4.5"), # slice thickness. requirted
                    ("0020|0052", "1.3.6.1.4.1.14519.5.2.1.7311.5101.283465068568757436662041653252"), # Frame of Reference UID Attribute(related with StudyUID). requirted
                    ("0020|0037", '\\'.join(map(str, (direction[0], direction[3], direction[6],# Image Orientation (Patient)
                                                        direction[1],direction[4],direction[7])))),
                    ("0008|103e", "	t2_tse_tra"), # Series Description
                    ("0020|1002", "241"), ## 图像slice的个数！

                    ]

    
    print(f"series instance UID is ", "1.2.826.0.1.3680043.2.1125."+modification_date+".1"+modification_time)
    # Write slices to output directory
    list(map(lambda i: writeSlices(series_tag_values, new_img, i, out_dir), range(new_img.GetDepth())))

def nifti2dicom_mfiles(nifti_dir, out_dir=''):
    """
    This function is to convert multiple nifti files into dicom files

    `nifti_dir`: You enter the global path to all of the nifti files here.
    `out_dir`: Put the path to where you want to save all the dicoms here.

    PS: Each nifti file's folders will be created automatically, so you do not need to create an empty folder for each patient.
    """

    images = glob(nifti_dir + '/*.nii.gz')

    for image in images:
        o_path = out_dir + '/' + os.path.basename(image)[:-7]
        os.makedirs(o_path, exist_ok=True)

        nifti2dicom_1file(image, o_path)


if __name__ == "__main__":
    nifti2dicom_1file(in_dir="./word_0002_0000.nii.gz", out_dir="./out_image_1")


